package com.atguigu.tingshu.user.service.impl;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import com.alibaba.csp.sentinel.util.AssertUtil;
import com.alibaba.fastjson.JSON;
import com.atguigu.tingshu.album.client.AlbumInfoFeignClient;
import com.atguigu.tingshu.album.client.TrackInfoFeignClient;
import com.atguigu.tingshu.common.constant.KafkaConstant;
import com.atguigu.tingshu.common.constant.RedisConstant;
import com.atguigu.tingshu.common.constant.SystemConstant;
import com.atguigu.tingshu.common.execption.GuiguException;
import com.atguigu.tingshu.common.result.Result;
import com.atguigu.tingshu.common.result.ResultCodeEnum;
import com.atguigu.tingshu.common.service.KafkaService;
import com.atguigu.tingshu.model.album.AlbumInfo;
import com.atguigu.tingshu.model.album.TrackInfo;
import com.atguigu.tingshu.model.user.*;
import com.atguigu.tingshu.user.mapper.*;
import com.atguigu.tingshu.user.service.UserInfoService;
import com.atguigu.tingshu.user.service.UserPaidTrackService;
import com.atguigu.tingshu.vo.user.UserInfoVo;
import com.atguigu.tingshu.vo.user.UserPaidRecordVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Assert;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
import org.joda.time.DateTime;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Slf4j
@Service
@SuppressWarnings({"unchecked", "rawtypes"})
public class UserInfoServiceImpl extends ServiceImpl<UserInfoMapper, UserInfo> implements UserInfoService {

    @Autowired
    private UserInfoMapper userInfoMapper;
    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private WxMaService wxMaService;

//	@Autowired
//	UserInfoService userInfoService;

    @Autowired
    private UserPaidAlbumMapper userPaidAlbumMapper;
    @Autowired
    private UserPaidTrackMapper userPaidTrackMapper;
    @Autowired
    private KafkaService kafkaService;

    @Qualifier("com.atguigu.tingshu.album.client.AlbumInfoFeignClient")
    @Autowired
    private AlbumInfoFeignClient albumInfoFeignClient;

    @Autowired
    private UserPaidTrackService userPaidTrackService;
    
    @Autowired
    private VipServiceConfigMapper vipServiceConfigMapper;
    
    @Autowired
    private UserVipServiceMapper userVipServiceMapper;

    @Qualifier("com.atguigu.tingshu.album.client.TrackInfoFeignClient")
    @Autowired
    private TrackInfoFeignClient trackInfoFeignClient;
    @Override
    public void updateUserPaidRecord(UserPaidRecordVo userPaidRecordVo) {
        String key="user_paid_record"+userPaidRecordVo.getOrderNo();
        Boolean aBoolean = redisTemplate.opsForValue().setIfAbsent(key, "1", 10, TimeUnit.SECONDS);
        if (!aBoolean){
            return;
        }
        try {
            if (userPaidRecordVo.getItemType().equals(SystemConstant.ORDER_ITEM_TYPE_ALBUM)) {
                // 创建用户支付记录对象
                UserPaidAlbum userPaidAlbum = new UserPaidAlbum();
                userPaidAlbum.setUserId(userPaidRecordVo.getUserId());
                userPaidAlbum.setAlbumId(userPaidRecordVo.getItemIdList().get(0));
                userPaidAlbum.setOrderNo(userPaidRecordVo.getOrderNo());
                userPaidAlbumMapper.insert(userPaidAlbum);
                // 购买声音
            } else if (userPaidRecordVo.getItemType().equals(SystemConstant.ORDER_ITEM_TYPE_TRACK)) {
                Result<TrackInfo> trackInfoResult = trackInfoFeignClient.getTrackInfo(userPaidRecordVo.getItemIdList().get(0));
                Assert.notNull(trackInfoResult, "专辑结果集不能为空");
                TrackInfo trackInfo = trackInfoResult.getData();
                Assert.notNull(trackInfo, "专辑不能为空");

                List<UserPaidTrack> userPaidTrackList = userPaidRecordVo.getItemIdList().stream().map(itemId -> {
                    UserPaidTrack userPaidTrack = new UserPaidTrack();
                    userPaidTrack.setUserId(userPaidRecordVo.getUserId());
                    userPaidTrack.setAlbumId(trackInfo.getAlbumId());
                    userPaidTrack.setTrackId(itemId);
                    userPaidTrack.setOrderNo(userPaidRecordVo.getOrderNo());
                    return userPaidTrack;
                }).collect(Collectors.toList());
                userPaidTrackService.saveBatch(userPaidTrackList);
                // vip 充值购买
            } else if (userPaidRecordVo.getItemType().equals(SystemConstant.ORDER_ITEM_TYPE_VIP)) {
                Long itemId = userPaidRecordVo.getItemIdList().get(0);
                VipServiceConfig vipServiceConfig = vipServiceConfigMapper.selectById(itemId);
                UserVipService userVipService = new UserVipService();
                userVipService.setUserId(userPaidRecordVo.getUserId());
                userVipService.setOrderNo(userPaidRecordVo.getOrderNo());
                //  获取当前系统时间
                Date startTime = new Date();
                //  vip 续期：
                //  获取用户信息
                UserInfo userInfo = this.getById(userPaidRecordVo.getUserId());
                // 当前用户属于vip 并 用户的过期时间大于当前系统时间，则需要重新计算vip 的过期时间。
                if (userInfo.getIsVip().intValue()==1 && userInfo.getVipExpireTime().after(new Date())){
                    startTime = userInfo.getVipExpireTime();
                }
                //  获取过期时间
                Date expireTime = new DateTime(startTime).plusMonths(vipServiceConfig.getServiceMonth()).toDate();
                userVipService.setStartTime(new Date());
                userVipService.setExpireTime(expireTime);
                userVipServiceMapper.insert(userVipService);
    
                //更新用户vip信息
                UserInfo userInfoUpt = new UserInfo();
                userInfoUpt.setId(userPaidRecordVo.getUserId());
                userInfoUpt.setIsVip(1);
                userInfoUpt.setVipExpireTime(expireTime);
                this.updateById(userInfoUpt);
    
            } else {
                log.info("无该项目类型：{}", JSON.toJSONString(userPaidRecordVo));
            }
        } catch (Exception e) {
            redisTemplate.delete(key);
            throw new RuntimeException(e);
        }

        
    }

    @Override
    public Boolean isPaidAlbum(Long userId, Long albumId) {
        Long count = userPaidAlbumMapper.selectCount(new LambdaQueryWrapper<UserPaidAlbum>().eq(UserPaidAlbum::getUserId, userId).eq(UserPaidAlbum::getAlbumId, albumId));
        if (count>0){
            return true;
        }
        return false;
    }

    @Override
    public List<Long> userIsPaidTrack(Long albumId, Long userId, List<Long> trackIdList) {
        LambdaQueryWrapper<UserPaidAlbum> userPaidAlbumLambdaQueryWrapper = new LambdaQueryWrapper<>();
        userPaidAlbumLambdaQueryWrapper.eq(UserPaidAlbum::getUserId, userId).eq(UserPaidAlbum::getAlbumId, albumId);
        UserPaidAlbum userPaidAlbum = userPaidAlbumMapper.selectOne(userPaidAlbumLambdaQueryWrapper);

        if (null != userPaidAlbum) {
           // List<Long> trackIdListAlbum = albumInfoFeignClient.getTrackByAlbumId(albumId);
            return   trackIdList;
        }else{
            List<Long> trackIdList1=new ArrayList<>();
            LambdaQueryWrapper<UserPaidTrack> userPaidTrackLambdaQueryWrapper = new LambdaQueryWrapper<>();
            userPaidTrackLambdaQueryWrapper.eq(UserPaidTrack::getUserId, userId).eq(UserPaidTrack::getAlbumId, albumId);
            List<UserPaidTrack> userPaidAlbums = userPaidTrackMapper.selectList(userPaidTrackLambdaQueryWrapper);
            if(!userPaidAlbums.isEmpty()){
               trackIdList1 = userPaidAlbums.stream().map(userPaidTrack -> userPaidTrack.getTrackId()).collect(Collectors.toList());

            }
            return trackIdList1;
        }

    }


    @Override
    public UserInfoVo getUserInfoVoByUserId(Long userId) {
        //	获取到用户信息对象
        UserInfo userInfo = this.getById(userId);
        //	创建UserInfoVo 对象
        UserInfoVo userInfoVo = new UserInfoVo();
        //	属性拷贝
        BeanUtils.copyProperties(userInfo, userInfoVo);
        return userInfoVo;
    }

    @Override
    public Map<String, Object> wxLogin(String code) {
        try {
            WxMaJscode2SessionResult sessionInfo = wxMaService.getUserService().getSessionInfo(code);
            //  学生端可以直接使用 wxcc651fcbab275e33 教师的 OPENID 即可
            String openId = sessionInfo.getOpenid();
            UserInfo userInfo = userInfoMapper.selectOne(new LambdaQueryWrapper<UserInfo>().eq(UserInfo::getWxOpenId, openId));
            //  如果数据库中没有这个对象
            if (null == userInfo) {
                //  创建对象
                userInfo = new UserInfo();
                userInfo.setNickname("听友" + System.currentTimeMillis());
                userInfo.setAvatarUrl("https://oss.aliyuncs.com/aliyun_id_photo_bucket/default_handsome.jpg");
                userInfo.setWxOpenId(openId);
                //this.save(userInfo);
                userInfoMapper.insert(userInfo);

                //  初始化账户信息
                kafkaService.sendMessage(KafkaConstant.QUEUE_USER_REGISTER, userInfo.getId().toString());
            }
            //  创建 token 并且存入redis用户信息
            String token = UUID.randomUUID().toString().replaceAll("-", "");
            redisTemplate.opsForValue().set(RedisConstant.USER_LOGIN_KEY_PREFIX + token, userInfo, RedisConstant.USER_LOGIN_KEY_TIMEOUT, TimeUnit.SECONDS);

            //  将这个数据存储到map中并返回
            HashMap<String, Object> map = new HashMap<>();
            map.put("token", token);
            //  返回数据
            return map;
        } catch (WxErrorException e) {
            throw new GuiguException(ResultCodeEnum.FAIL);
        }
    }
}
